package asia.kalin.service.impl;

import asia.kalin.domain.ao.Result;
import asia.kalin.domain.po.Dispose;
import asia.kalin.domain.po.UserInfo;
import asia.kalin.domain.vo.DetectionResultVO;
import asia.kalin.enums.RedisKeyEnums;
import asia.kalin.mapper.DisposeMapper;
import asia.kalin.mapper.UserInfoMapper;
import asia.kalin.service.IDisposeService;
import asia.kalin.utils.RedisLock;
import asia.kalin.utils.ThreadLocalUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Kalin
 * @since 2025-03-10
 */
@Service
@RequiredArgsConstructor
public class DisposeServiceImpl extends ServiceImpl<DisposeMapper, Dispose> implements IDisposeService {

    private final StringRedisTemplate stringRedisTemplate;

    private final UserInfoMapper userInfoMapper;

    /**
     * 接手检测结果
     * @param resultId
     * @return
     */
    @Override
    @Transactional
    public Result takeOverResult(String resultId) {
        // 获取用户id
        Map<String,Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");

        // 创建锁
        RedisLock redisLock = new RedisLock(userId, stringRedisTemplate);
        boolean isLock = redisLock.tryLock(2);

        if(!isLock){
            return new Result<>(1,"当前检测结果正在被其他人操作",null);
        }

        // 处理逻辑
        try {
            // 查询出当前id的结果处理
            Dispose dispose = baseMapper.selectOne(
                    new QueryWrapper<Dispose>().lambda().eq(Dispose::getResultId, resultId)
            );

            if(dispose == null){
                return new Result<>(1,"检测结果id不存在",null);
            }

            if(dispose.getUserId() != null && !StrUtil.isBlank(dispose.getUserId()) && !StrUtil.isEmpty(dispose.getUserId())){
                return new Result<>(1,"当前检测结果已经被接手",null);
            }

            // 查询出当前用户信息
            UserInfo userInfo = userInfoMapper.selectOne(
                    new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getUserId, userId)
            );

            // 将当前用户的userId departmentId填入结果处理 代表接手这个任务
            dispose.setUserId(userInfo.getUserId());
            dispose.setDepartmentId(userInfo.getDepartmentId());

            // 修改数据库
            int i = baseMapper.updateById(dispose);
            if(i <= 0){
                return new Result<>(1,"接手失败",null);
            }
        } finally {
            // 释放锁
            redisLock.unlock();
        }

        // 删除相关redis
        stringRedisTemplate.delete(RedisKeyEnums.DETECTION_RESULT_TYPE_KEY);
        stringRedisTemplate.delete(RedisKeyEnums.DISPOSE_PROCESSING_USERID_KEY + userId);

        return new Result<>(0,"接手成功",null);
    }

    /**
     * 取消已经接手的检测结果
     * @param resultId 检测结果id
     * @return Result
     */
    @Override
    public Result callOffResult(String resultId) {
        // 得到当前用户id
        Map<String,Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");

        // 查询出结果处理
        Dispose dispose = baseMapper.selectOne(
                new QueryWrapper<Dispose>().lambda().eq(Dispose::getResultId, resultId)
        );

        if(dispose.getUserId() == null || StrUtil.isBlank(dispose.getUserId()) || StrUtil.isEmpty(dispose.getUserId())){
            return new Result<>(1,"当前订单未有人接手 无需取消",null);
        }

        // 如果userId和结果处理负责人不一致则不让修改
        if(!userId.equals(dispose.getUserId())){
            return new Result<>(1,"只能取消自己负责的处理结果",null);
        }

        // 修改数据库数据
        dispose.setUserId("");
        dispose.setDepartmentId("");
        int i = baseMapper.updateById(dispose);
        if(i <= 0){
            return new Result<>(1,"取消失败",null);
        }

        // 删除相关redis
        // 删除查询当前用户已经解决的检测结果Redis
        stringRedisTemplate.delete(RedisKeyEnums.DISPOSE_RESOLVED_USERID_KEY + userId);
        stringRedisTemplate.delete(RedisKeyEnums.DISPOSE_PROCESSING_USERID_KEY + userId);

        return new Result<>(0,"取消成功",null);
    }

    /**
     * 查询当前用户的已经结果的处理结果
     * @return Result
     */
    @Override
    public Result getDisposeResolvedByUserId() {
        // 得到当前用户id
        Map<String,Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");
        // 拼接key
        String key = RedisKeyEnums.DISPOSE_RESOLVED_USERID_KEY + userId;
        // 查询redis
        String object = stringRedisTemplate.opsForValue().get(key);
        // 判断是否存在
        if(StrUtil.isNotBlank(object)){
            // 转换成对应类型
            List<DetectionResultVO> detectionResultVOList = JSONUtil.toList(object, DetectionResultVO.class);
            return new Result<>(0,"查询成功",detectionResultVOList);
        }

        // 不存在 查询数据库
        // 查询出用户所有解决的Dispose结果
        List<DetectionResultVO> detectionResultVOList = baseMapper.getDetectionResolvedByUserId(userId,1);
        // 如果查询结果为空 那么用户还没有已经解决的检测结果
        if(detectionResultVOList.isEmpty())
            return new Result<>(1,"当前没有已经解决的处理结果",null);

        // 转换成JSON
        // 创建一个JSONConfig对象
        JSONConfig config = new JSONConfig();
        // 设置日期格式
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        String jsonStr = JSONUtil.toJsonStr(detectionResultVOList,config);

        // 写入redis
        stringRedisTemplate.opsForValue().set(key,jsonStr,RedisKeyEnums.DISPOSE_RESOLVED_USERID_TTL, TimeUnit.HOURS);

        return new Result<>(0,"查询成功",detectionResultVOList);
    }

    /**
     * 更新处理结果状态为解决
     * @param resultId 检测结果ID
     * @return Result
     */
    @Override
    public Result updateStateSolvedById(String resultId) {
        // 得到当前用户id
        Map<String,Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");

        // 创建一个对象
        Dispose dispose = new Dispose();
        dispose.setResultId(resultId);
        dispose.setUserId(userId);
        dispose.setState(1);

        int i = baseMapper.update(dispose, new QueryWrapper<Dispose>()
                .eq("user_id", dispose.getUserId())
                .eq("result_id", dispose.getResultId())
        );

        if(i <= 0){
            return new Result<>(1,"更新失败",null);
        }

        // 删除相关redis
        stringRedisTemplate.delete(RedisKeyEnums.DISPOSE_RESOLVED_USERID_KEY + userId);
        stringRedisTemplate.delete(RedisKeyEnums.DISPOSE_PROCESSING_USERID_KEY + userId);

        return new Result<>(0,"更新成功",null);
    }

    /**
     * 查询当前正在处理（未解决）的检测结果
     * @return Result
     */
    @Override
    public Result getProcessingDisposeByUserId() {
        // 得到当前用户id
        Map<String,Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");

        // 拼接key
        String key = RedisKeyEnums.DISPOSE_PROCESSING_USERID_KEY + userId;
        // 查询redis
        String object = stringRedisTemplate.opsForValue().get(key);
        // 判断是否存在
        if(StrUtil.isNotBlank(object)){
            // 转换成对应类型
            List<DetectionResultVO> detectionResultVOList = JSONUtil.toList(object, DetectionResultVO.class);
            return new Result<>(0,"查询成功",detectionResultVOList);
        }

        // 不存在 查询数据库
        // 查询出用户所有解决的Dispose结果
        List<DetectionResultVO> detectionResultVOList = baseMapper.getDetectionResolvedByUserId(userId,0);
        // 如果查询结果为空 那么用户还没有已经解决的检测结果
        if(detectionResultVOList.isEmpty())
            return new Result<>(1,"当前没有正在解决的处理结果",null);

        // 转换成JSON
        // 创建一个JSONConfig对象
        JSONConfig config = new JSONConfig();
        // 设置日期格式
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        String jsonStr = JSONUtil.toJsonStr(detectionResultVOList,config);

        // 写入redis
        stringRedisTemplate.opsForValue().set(key,jsonStr,RedisKeyEnums.DISPOSE_PROCESSING_USERID_TTL, TimeUnit.HOURS);

        return new Result<>(0,"查询成功",detectionResultVOList);
    }

    @Override
    public Result isHaveUserById(String resultId) {
        Dispose dispose = baseMapper.selectOne(
                new QueryWrapper<Dispose>()
                        .eq("result_id", resultId)
        );

        if(dispose == null){
            return new Result<>(1,"ID错误",null);
        }

        if(dispose.getUserId() == null || dispose.getDepartmentId() == null){
            return new Result<>(0,"无接手",null);
        }

        return new Result<>(1,"有接手",null);
    }
}
